package com.timeshare.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.timeshare.dto.SkillRequest;
import com.timeshare.dto.SkillVO;
import com.timeshare.entity.Favorite;
import com.timeshare.entity.Skill;
import com.timeshare.entity.User;
import com.timeshare.mapper.FavoriteMapper;
import com.timeshare.mapper.SkillMapper;
import com.timeshare.mapper.UserMapper;
import com.timeshare.service.SkillService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 技能服务实现
 */
@Service
public class SkillServiceImpl extends ServiceImpl<SkillMapper, Skill> implements SkillService {
    
    private final UserMapper userMapper;
    private final FavoriteMapper favoriteMapper;
    
    // 技能分类映射
    private static final Map<Integer, String> CATEGORY_MAP = new HashMap<>();
    static {
        CATEGORY_MAP.put(1, "学习类");
        CATEGORY_MAP.put(2, "生活类");
        CATEGORY_MAP.put(3, "艺术类");
        CATEGORY_MAP.put(4, "编程类");
        CATEGORY_MAP.put(5, "其他");
    }
    
    public SkillServiceImpl(UserMapper userMapper, FavoriteMapper favoriteMapper) {
        this.userMapper = userMapper;
        this.favoriteMapper = favoriteMapper;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishSkill(Long userId, SkillRequest request) {
        Skill skill = new Skill();
        BeanUtil.copyProperties(request, skill);
        skill.setUserId(userId);
        skill.setViewCount(0);
        skill.setFavoriteCount(0);
        skill.setAppointmentCount(0);
        skill.setStatus(0); // 待审核
        this.save(skill);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSkill(Long userId, Long skillId, SkillRequest request) {
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        if (!skill.getUserId().equals(userId)) {
            throw new RuntimeException("无权修改此技能");
        }
        
        BeanUtil.copyProperties(request, skill, "id", "userId");
        this.updateById(skill);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSkill(Long userId, Long skillId) {
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        if (!skill.getUserId().equals(userId)) {
            throw new RuntimeException("无权删除此技能");
        }
        
        this.removeById(skillId);
    }
    
    @Override
    public Page<SkillVO> getSkillList(Long userId, Integer category, String keyword, Integer page, Integer size) {
        Page<Skill> skillPage = new Page<>(page, size);
        LambdaQueryWrapper<Skill> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Skill::getStatus, 1); // 只查询已发布的
        
        if (category != null && category > 0) {
            wrapper.eq(Skill::getCategory, category);
        }
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w.like(Skill::getTitle, keyword)
                    .or().like(Skill::getDescription, keyword)
                    .or().like(Skill::getTags, keyword));
        }
        
        wrapper.orderByDesc(Skill::getCreateTime);
        this.page(skillPage, wrapper);
        
        return convertToVOPage(skillPage, userId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SkillVO getSkillDetail(Long userId, Long skillId) {
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        
        // 增加浏览次数
        skill.setViewCount(skill.getViewCount() + 1);
        this.updateById(skill);
        
        return convertToVO(skill, userId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void toggleFavorite(Long userId, Long skillId) {
        // 检查技能是否存在
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        
        // 检查是否已收藏
        LambdaQueryWrapper<Favorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Favorite::getUserId, userId)
               .eq(Favorite::getSkillId, skillId);
        Favorite favorite = favoriteMapper.selectOne(wrapper);
        
        if (favorite != null) {
            // 取消收藏
            favoriteMapper.deleteById(favorite.getId());
            skill.setFavoriteCount(Math.max(0, skill.getFavoriteCount() - 1));
        } else {
            // 添加收藏
            favorite = new Favorite();
            favorite.setUserId(userId);
            favorite.setSkillId(skillId);
            favoriteMapper.insert(favorite);
            skill.setFavoriteCount(skill.getFavoriteCount() + 1);
        }
        
        this.updateById(skill);
    }
    
    @Override
    public Page<SkillVO> getMySkills(Long userId, Integer page, Integer size) {
        Page<Skill> skillPage = new Page<>(page, size);
        LambdaQueryWrapper<Skill> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Skill::getUserId, userId)
               .orderByDesc(Skill::getCreateTime);
        this.page(skillPage, wrapper);
        
        return convertToVOPage(skillPage, userId);
    }
    
    @Override
    public Page<SkillVO> getMyFavorites(Long userId, Integer page, Integer size) {
        // 查询收藏的技能ID列表
        LambdaQueryWrapper<Favorite> favoriteWrapper = new LambdaQueryWrapper<>();
        favoriteWrapper.eq(Favorite::getUserId, userId);
        List<Favorite> favorites = favoriteMapper.selectList(favoriteWrapper);
        
        if (favorites.isEmpty()) {
            return new Page<>(page, size);
        }
        
        List<Long> skillIds = favorites.stream()
                .map(Favorite::getSkillId)
                .collect(Collectors.toList());
        
        Page<Skill> skillPage = new Page<>(page, size);
        LambdaQueryWrapper<Skill> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Skill::getId, skillIds)
               .orderByDesc(Skill::getCreateTime);
        this.page(skillPage, wrapper);
        
        return convertToVOPage(skillPage, userId);
    }
    
    /**
     * 转换为VO对象
     */
    private SkillVO convertToVO(Skill skill, Long currentUserId) {
        SkillVO vo = new SkillVO();
        BeanUtil.copyProperties(skill, vo);
        
        // 查询用户信息
        User user = userMapper.selectById(skill.getUserId());
        if (user != null) {
            vo.setUsername(user.getUsername());
            vo.setUserNickname(user.getNickname());
            vo.setUserAvatar(user.getAvatar());
        }
        
        // 设置分类名称
        vo.setCategoryName(CATEGORY_MAP.get(skill.getCategory()));
        
        // 检查是否已收藏
        if (currentUserId != null) {
            LambdaQueryWrapper<Favorite> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Favorite::getUserId, currentUserId)
                   .eq(Favorite::getSkillId, skill.getId());
            vo.setIsFavorited(favoriteMapper.selectCount(wrapper) > 0);
        }
        
        return vo;
    }
    
    /**
     * 转换为VO分页对象
     */
    private Page<SkillVO> convertToVOPage(Page<Skill> skillPage, Long currentUserId) {
        Page<SkillVO> voPage = new Page<>(skillPage.getCurrent(), skillPage.getSize(), skillPage.getTotal());
        List<SkillVO> voList = skillPage.getRecords().stream()
                .map(skill -> convertToVO(skill, currentUserId))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }
    
    @Override
    public Page<SkillVO> getPendingSkills(Integer page, Integer size) {
        Page<Skill> skillPage = new Page<>(page, size);
        LambdaQueryWrapper<Skill> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Skill::getStatus, 0) // 待审核
               .orderByDesc(Skill::getCreateTime);
        this.page(skillPage, wrapper);
        return convertToVOPage(skillPage, null);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveSkill(Long skillId) {
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        skill.setStatus(1); // 已发布
        this.updateById(skill);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rejectSkill(Long skillId, String reason) {
        Skill skill = this.getById(skillId);
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        skill.setStatus(2); // 已拒绝
        this.updateById(skill);
    }
}

